package com.qf.mybatisplus.aspect;

import com.qf.mybatisplus.utils.DesUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.List;

/**
 * @ClassName: DecryptAspect
 * @Author:Cola.Niu
 * @date:2020/4/22 9:57
 * @Version:v1.0
 * @description: 解密切面
 */
@Aspect
@Component
public class DecryptAspect {
    @Pointcut("@annotation(com.qf.mybatisplus.aspect.Decrypt)")
    public void decryptPointCut() {
    }

    @AfterReturning(returning = "result",pointcut = "decryptPointCut()")
    public void after(JoinPoint point, Object result){
        //获得方法注解列表
        MethodSignature signature= (MethodSignature) point.getSignature();
        if (result!=null){
            if (result instanceof String){
                result = DesUtil.decrypt((String)result);
            }else if (result instanceof List){
                for (int i = 0; i < ((List) result).size(); i++) {
                    Object o = decrypt(((List) result).get(i));
//                    ((List) result).add(o);
                }
            }else{
                result = decrypt(result);
            }
        }

    }

    /**
     * 将对象o上有@EncryptParam注解的属性进行解密
     * @param o
     */
    private Object decrypt(Object o){
        Class c = o.getClass();
        //获得所有的属性
        Field[] fields =  c.getDeclaredFields();
        for (Field field : fields) {
            //判断是否存在EncryptParam注解
            if (field.getAnnotation(EncryptParam.class)!=null){
                //对该字段进行解密
                field.setAccessible(true);
                try {
                    //只对String类型解密
                    if (field.get(o) instanceof String){
                        field.set(o, DesUtil.decrypt((String)field.get(o)));
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
        return o;
    }
}
